#pragma once
#include "object_pool.h"
#include <boost/asio.hpp>
class AsyncTimer;
typedef std::function<void(const boost::system::error_code&)> timer_callback;

class Timer
{
public:
	Timer()
		:timer(NULL)
	{
	}
	~Timer()
	{
		stop();
		delete timer;
	}
	void init(boost::asio::io_service* io_context, int second, timer_callback func_cb, AsyncTimer* ptr, bool reclaim = true)
	{
		_reclaim = reclaim;
		_parent = ptr;
		io_context_ = io_context;
		sec = second;
		_func_cb = func_cb;
		stop();
		if (timer)
		{
			delete timer;
		}
		timer = new boost::asio::deadline_timer(*io_context_, boost::posix_time::seconds(sec));
	}
	inline void start()
	{
		if (timer)
		{
			//timer->expires_at(timer->expires_at());
			timer->async_wait(_func_cb);
		}
	}
	inline void stop()
	{
		if (timer) timer->cancel();
	}
private:
	bool				_reclaim;
	boost::asio::deadline_timer* timer;
	timer_callback		_func_cb;
	boost::asio::io_service* io_context_;
	int	sec;
	AsyncTimer*			_parent;
};

class GameTimer2
{
public:
	GameTimer2() :_timer(nullptr)
	{}
protected:
	inline bool init(Timer* timer)
	{
		_timer = timer;
		return (_timer != nullptr);
	}
	inline void again()
	{
		if (_timer)
		{
			_timer->start();
		}
	}
public:
	inline bool operator = (Timer* timer)
	{
		return init(timer);
	}
	inline bool run()
	{
		if (_timer)
		{
			_timer->start();
			return true;
		}
		return false;
	}
	inline bool start()
	{
		return run();
	}
	inline void stop()
	{
		if (_timer)
		{
			_timer->stop();
		}
	}
public:
	Timer * _timer;
};


class AsyncTimer : public ObjectPool<Timer>
{
public:
	AsyncTimer(boost::asio::io_service* io_context)
		: io_context_(io_context)
	{}
	~AsyncTimer()
	{
	}
	//初始化定时器 包含初始化
	bool InitTimer(GameTimer2& timer, int seconds, timer_callback fn)
	{
		return (timer = Async(seconds, false, fn));
	}
	//运行定时器 包含了初始化和执行
	bool RunTimer(GameTimer2& timer, int seconds, timer_callback fn)
	{
		if (!timer.run())
		{
			if (timer = Async(seconds, false, fn))
			{
				return timer.run();
			}
			return false;
		}
		return true;
	}
	//运行一次性的，不可操纵的定时器，普通的定时异步过程，开始了就不可手动停止
	bool RunOnce(int seconds, timer_callback fn)
	{
		Async(seconds, true, fn);
		return true;
	}
protected:
	//reclaim是否会自动回收，即是否是一次性的
	Timer * Async(int seconds, bool reclaim, timer_callback fn)
	{
		Timer* timer = Pop();
		timer->init(io_context_, seconds, fn, this, reclaim);
		if (reclaim)
		{
			timer->start();
			return nullptr;
		}
		return timer;
	}

private:
	boost::asio::io_service* io_context_;
};